home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Games / NeXTGo / Source / score.c < prev    next >
C/C++ Source or Header  |  1993-02-08  |  10KB  |  492 lines

  1. #include "comment.header"
  2.  
  3. /*  Define the following to debug the scoring routine.  */
  4. /*  #define _DEBUG_SCORING_  */
  5.  
  6. #define EMPTY        0
  7. #define WHITESTONE   1
  8. #define BLACKSTONE   2
  9. #define NEUTRAL_TERR 3
  10. #define WHITE_TERR   4
  11. #define BLACK_TERR   5
  12.  
  13. extern unsigned char p[19][19];
  14. extern int MAXX, MAXY;
  15. extern int blackCaptured, whiteCaptured, blackTerritory, whiteTerritory;
  16. unsigned char mark[19][19], ownermat[19][19], scoringmat[19][19];
  17. unsigned char newpatternmat[19][19], tempmat[19][19], patternmat[19][19];
  18.  
  19. #ifdef _DEBUG_SCORING_
  20. #include <stdio.h>
  21.  
  22. void display_board(void)
  23. {
  24.   int i, j;
  25.  
  26.   printf("\n\n");
  27.   for (i = 0; i < MAXX; i++)
  28.     {
  29.       for (j = 0; j < MAXY; j++)
  30.     switch (p[i][j])
  31.       {
  32.       case 0: 
  33.         printf("+");
  34.         break;
  35.       case 1:
  36.         printf("O");
  37.         break;
  38.       case 2:
  39.         printf("X");
  40.       }
  41.       printf("\n");
  42.     }
  43. }
  44. #endif
  45.  
  46. void set_temp_to_patternmat(void)
  47. {
  48.   int i, j;
  49.  
  50.   for (i = 0; i < MAXX; i++)
  51.     for (j = 0; j < MAXY; j++)
  52.       newpatternmat[i][j] = patternmat[i][j];
  53. }
  54.  
  55. void set_patternmat_to_temp(void)
  56. {
  57.   int i, j;
  58.  
  59.   for (i = 0; i < MAXX; i++)
  60.     for (j = 0; j < MAXY; j++)
  61.       patternmat[i][j] = newpatternmat[i][j];
  62. }
  63.  
  64. void set_p_to_temp(void)
  65. /*  Copy the board to a temporary array.  */
  66. {
  67.   int i, j;
  68.  
  69.   for (i = 0; i < MAXX; i++)
  70.     for (j = 0; j < MAXY; j++)
  71.       p[i][j] = tempmat[i][j];
  72. }
  73.  
  74. void set_temp_to_p(void)
  75. /*  Copy the temporary array to the board.  */
  76. {
  77.   int i, j;
  78.  
  79.   for (i = 0; i < MAXX; i++)
  80.     for (j = 0; j < MAXY; j++)
  81.       tempmat[i][j] = p[i][j];
  82. }
  83.  
  84. void find_pattern_in_board(int x, int y)
  85. /*  Find a pattern of stones or blank spots in the board.  */
  86. {
  87.   int i, j, changes = 1, minx, maxx, miny, maxy;
  88.  
  89.   for (i = 0; i < MAXX; i++)
  90.     for (j = 0; j < MAXY; j++)
  91.       patternmat[i][j] = EMPTY;
  92.  
  93.   patternmat[x][y] = 1;
  94.   minx = (x>0)?x-1:0;
  95.   maxx = (x<MAXX-1)?x+1:MAXX-1;
  96.   miny = (y>0)?y-1:0;
  97.   maxy = (y<MAXY-1)?y+1:MAXY-1;
  98.  
  99.   while (changes)
  100.     {
  101.       changes = 0;
  102.       set_temp_to_patternmat();
  103.       for (i = minx; i <= maxx; i++)
  104.     for (j = miny; j <= maxy; j++)
  105.       if (patternmat[i][j] == EMPTY)
  106.       {
  107.         /*  Check northern neighbor.  */
  108.         if (i > 0)
  109.           {
  110.         if ((patternmat[i-1][j]) && (p[i][j] == p[i-1][j]))
  111.           {
  112.             changes++;
  113.             if (i + 1 > maxx)
  114.               maxx = (i+1<MAXX-1)?i+1:MAXX-1;
  115.             newpatternmat[i][j] = 1;
  116.           }
  117.           }
  118.  
  119.         /*  Check eastern neighbor.  */
  120.         if (j < MAXY - 1)
  121.           {
  122.         if ((patternmat[i][j+1]) && (p[i][j] == p[i][j+1]))
  123.           {
  124.             changes++;
  125.             if (j - 1 < miny)
  126.               miny = (j-1>0)?j-1:0;
  127.             newpatternmat[i][j] = 1;
  128.           }
  129.           }
  130.  
  131.         /*  Check southern neighbor.  */
  132.         if (i < MAXX - 1)
  133.           {
  134.         if ((patternmat[i+1][j]) && (p[i][j] == p[i+1][j]))
  135.           {
  136.             changes++;
  137.             if (i - 1 < minx)
  138.               minx = (i-1>0)?i-1:0;
  139.             newpatternmat[i][j] = 1;
  140.           }
  141.           }
  142.  
  143.         /*  Check western neighbor.  */
  144.         if (j > 0)
  145.           {
  146.         if ((patternmat[i][j-1]) && (p[i][j] == p[i][j-1]))
  147.           {
  148.             changes++;
  149.             if (j + 1 > maxy)
  150.               maxy = (j+1<MAXY-1)?j+1:MAXY-1;
  151.             newpatternmat[i][j] = 1;
  152.           }
  153.           }
  154.       }
  155.       set_patternmat_to_temp();
  156.     }
  157. }
  158.  
  159. void find_owner0(int x, int y)
  160. /*  Routine to the find the owner of the blank spot at x, y.  */
  161. {
  162.   int i, j, changes = 1, owner = 0, minx, maxx, miny, maxy;
  163.  
  164. /*  clear_mat(patternmat);  */
  165.   for (i = 0; i < MAXX; i++)
  166.     for (j = 0; j < MAXY; j++)
  167.       patternmat[i][j] = EMPTY;
  168.  
  169.   patternmat[x][y] = mark[x][y] = 1;
  170.   minx = (x>0)?x-1:0;
  171.   maxx = (x<MAXX-1)?x+1:MAXX-1;
  172.   miny = (y>0)?y-1:0;
  173.   maxy = (y<MAXY-1)?y+1:MAXY-1;
  174.  
  175.   while (changes)
  176.     {
  177.       changes = 0;
  178.       set_temp_to_patternmat();
  179.       for (i = minx; i <= maxx; i++)
  180.     for (j = miny; j <= maxy; j++)
  181.       if (patternmat[i][j] == EMPTY)
  182.       {
  183.         /*  Check northern neighbor.  */
  184.         if (i > 0)
  185.           {
  186.         if (patternmat[i-1][j])
  187.           {
  188.             if (p[i][j] == EMPTY)
  189.               {
  190.             changes++;
  191.             if (i + 1 > maxx)
  192.               maxx = (i+1<MAXX-1)?i+1:MAXX-1;
  193.             newpatternmat[i][j] = mark[i][j] = 1;
  194.               }
  195.             else
  196.               {
  197.             if (owner == 0)
  198.               owner = p[i][j];
  199.             else if (owner != p[i][j])
  200.               owner = NEUTRAL_TERR;
  201.               }
  202.           }
  203.           }
  204.  
  205.         /*  Check eastern neighbor.  */
  206.         if (j < MAXY - 1)
  207.           {
  208.         if (patternmat[i][j+1])
  209.           {
  210.             if (p[i][j] == 0)
  211.               {
  212.             changes++;
  213.             if (j - 1 < miny)
  214.               miny = (j-1>0)?j-1:0;
  215.             newpatternmat[i][j] = mark[i][j] = 1;
  216.               }
  217.             else
  218.               {
  219.             if (owner == 0)
  220.               owner = p[i][j];
  221.             else if (owner != p[i][j])
  222.               owner = NEUTRAL_TERR;
  223.               }
  224.           }
  225.           }
  226.  
  227.         /*  Check southern neighbor.  */
  228.         if (i < MAXX - 1)
  229.           {
  230.         if (patternmat[i+1][j])
  231.           {
  232.             if (p[i][j] == 0)
  233.               {
  234.             changes++;
  235.             if (i - 1 < minx)
  236.               minx = (i-1>0)?i-1:0;
  237.             newpatternmat[i][j] = mark[i][j] = 1;
  238.               }
  239.             else
  240.               {
  241.             if (owner == 0)
  242.               owner = p[i][j];
  243.             else if (owner != p[i][j])
  244.               owner = NEUTRAL_TERR;
  245.               }
  246.           }
  247.           }
  248.  
  249.         /*  Check western neighbor.  */
  250.         if (j > 0)
  251.           {
  252.         if (patternmat[i][j-1])
  253.           {
  254.             if (p[i][j] == 0)
  255.               {
  256.             changes++;
  257.             if (j + 1 > maxy)
  258.               maxy = (j+1<MAXY-1)?j+1:MAXY-1;
  259.             newpatternmat[i][j] = mark[i][j] = 1;
  260.               }
  261.             else
  262.               {
  263.             if (owner == 0)
  264.               owner = p[i][j];
  265.             else if (owner != p[i][j])
  266.               owner = NEUTRAL_TERR;
  267.               }
  268.           }
  269.           }
  270.       }
  271.       set_patternmat_to_temp();
  272.     }
  273.  
  274.   for (i = 0; i < MAXX; i++)
  275.     for (j = 0; j < MAXX; j++)
  276.       if (patternmat[i][j])
  277.     ownermat[i][j] = owner;
  278. }
  279.  
  280. void find_owner(void)
  281. /*  Determine ownership of all empty points.  */
  282. {
  283.   int i, j;
  284.  
  285.   for (i = 0; i < MAXX; i++)
  286.     for (j = 0; j < MAXY; j++)
  287.       {
  288.     mark[i][j] = EMPTY;
  289.     ownermat[i][j] = EMPTY;
  290.       }
  291.  
  292.   for (i = 0; i < MAXX; i++)
  293.     for (j = 0; j < MAXY; j++)
  294.       if ((p[i][j] == EMPTY) && (mark[i][j] == EMPTY))
  295.     find_owner0(i, j);
  296. }
  297.  
  298. int surrounds_territory(int x, int y)
  299. /*  Determine if the stones at x, y surround any territory.  */
  300. {
  301.   int i, j, currentcolor = p[x][y], changes = 1, minx, maxx, miny, maxy;
  302.  
  303.   for (i = 0; i < MAXX; i++)
  304.     for (j = 0; j < MAXY; j++)
  305.       patternmat[i][j] = EMPTY;
  306.  
  307.   patternmat[x][y] = 1;
  308.   minx = (x>0)?x-1:0;
  309.   maxx = (x<MAXX-1)?x+1:MAXX-1;
  310.   miny = (y>0)?y-1:0;
  311.   maxy = (y<MAXY-1)?y+1:MAXY-1;
  312.  
  313.   while (changes)
  314.     {
  315.       changes = 0;
  316.       set_temp_to_patternmat();
  317.       for (i = 0; i < MAXX; i++)
  318.     for (j = 0; j < MAXY; j++)
  319.       if (patternmat[i][j] == 0)
  320.       {
  321.         /*  Check northern neighbor.  */
  322.         if (i > 0)
  323.           {
  324.         if (patternmat[i-1][j])
  325.           {
  326.             if (p[i][j] == 0)
  327.               {
  328.             if (ownermat[i][j] == currentcolor)
  329.               return 1;
  330.               }
  331.             else
  332.               {
  333.             if (p[i][j] == currentcolor)
  334.               {
  335.                 changes++;
  336.                 if (i + 1 > maxx)
  337.                   maxx = (i+1<MAXX-1)?i+1:MAXX-1;
  338.                 newpatternmat[i][j] = 1;
  339.               }
  340.               }
  341.           }
  342.           }
  343.  
  344.         /*  Check eastern neighbor.  */
  345.         if (j < MAXY - 1)
  346.           {
  347.         if (patternmat[i][j+1])
  348.           {
  349.             if (p[i][j] == 0)
  350.               {
  351.             if (ownermat[i][j] == currentcolor)
  352.               return 1;
  353.               }
  354.             else
  355.               {
  356.             if (p[i][j] == currentcolor)
  357.               {
  358.                 changes++;
  359.                 if (j - 1 < miny)
  360.                   miny = (j-1>0)?j-1:0;
  361.                 newpatternmat[i][j] = 1;
  362.               }
  363.               }
  364.           }
  365.           }
  366.  
  367.         /*  Check southern neighbor.  */
  368.         if (i < MAXX - 1)
  369.           {
  370.         if (patternmat[i+1][j])
  371.           {
  372.             if (p[i][j] == 0)
  373.               {
  374.             if (ownermat[i][j] == currentcolor)
  375.               return 1;
  376.               }
  377.             else
  378.               {
  379.             if (p[i][j] == currentcolor)
  380.               {
  381.                 changes++;
  382.                 if (i - 1 < minx)
  383.                   minx = (i-1>0)?i-1:0;
  384.                 newpatternmat[i][j] = 1;
  385.               }
  386.               }
  387.           }
  388.           }
  389.  
  390.         /*  Check western neighbor.  */
  391.         if (j > 0)
  392.           {
  393.         if (patternmat[i][j-1])
  394.           {
  395.             if (p[i][j] == 0)
  396.               {
  397.             if (ownermat[i][j] == currentcolor)
  398.               return 1;
  399.               }
  400.             else
  401.               {
  402.             if (p[i][j] == currentcolor)
  403.               {
  404.                 changes++;
  405.                 if (j + 1 > maxy)
  406.                   maxy = (j+1<MAXY-1)?j+1:MAXY-1;
  407.                 newpatternmat[i][j] = 1;
  408.               }
  409.               }
  410.           }
  411.           }
  412.       }
  413.       set_patternmat_to_temp();
  414.     }
  415.  
  416.   return 0;
  417. }
  418.  
  419. void score_game(void)
  420. /*  Score the game and remove dead stones.  */
  421. {
  422.   int i, j, k, l, changes = 1, num_in_pattern;
  423.  
  424.   for (i = 0; i < MAXX; i++)
  425.     for (j = 0; j < MAXY; j++)
  426.       scoringmat[i][j] = EMPTY;
  427.  
  428.   while (changes)
  429.     {
  430.       changes = 0;
  431.       find_owner();
  432.  
  433.       for (i = 0; i < MAXX; i++)
  434.     for (j = 0; j < MAXY; j++)
  435.       if ((p[i][j] != EMPTY) && (scoringmat[i][j] == EMPTY))
  436.         {
  437.           if (surrounds_territory(i, j))
  438.         {
  439.           find_pattern_in_board(i, j);
  440.  
  441.           for (k = 0; k < MAXX; k++)
  442.             for (l = 0; l < MAXY; l++)
  443.               if (patternmat[k][l])
  444.             scoringmat[k][l] = p[k][l];
  445.         }
  446.           else
  447.         {
  448.           find_pattern_in_board(i, j);
  449.           set_temp_to_p();
  450.           num_in_pattern = 0;
  451.  
  452.           for (k = 0; k < MAXX; k++)
  453.             for (l = 0; l < MAXY; l++)
  454.               if (patternmat[k][l])
  455.             {
  456.               p[k][l] = EMPTY;
  457.               num_in_pattern++;
  458.             }
  459.  
  460.           find_owner();
  461.  
  462.           if ((ownermat[i][j] != NEUTRAL_TERR) &&
  463.               (ownermat[i][j] != tempmat[i][j]))
  464.             {
  465.               if (tempmat[i][j] == BLACKSTONE)
  466.             blackCaptured += num_in_pattern;
  467.               else
  468.             whiteCaptured += num_in_pattern;
  469.               changes++;
  470.             }
  471.           else
  472.             {
  473.               set_p_to_temp();
  474.               find_owner();
  475.             }
  476.         }
  477.         }
  478.     }
  479.  
  480.   blackTerritory = 0;
  481.   whiteTerritory = 0;
  482.  
  483.   for (i = 0; i < MAXX; i++)
  484.     for (j = 0; j < MAXY; j++)
  485.       {
  486.     if (ownermat[i][j] == BLACKSTONE)
  487.       blackTerritory++;
  488.     if (ownermat[i][j] == WHITESTONE)
  489.       whiteTerritory++;
  490.       }
  491. }
  492.